package commands

import (
	"encoding/json"
	"fmt"
	"os"
	"reflect"
	"strings"
	"text/tabwriter"

	"gopkg.in/yaml.v3"
)

// printOutput 根据格式输出数据
func printOutput(data interface{}, format string) error {
	switch format {
	case "json":
		jsonData, err := json.MarshalIndent(data, "", "  ")
		if err != nil {
			return fmt.Errorf("JSON 格式化失败: %w", err)
		}
		fmt.Println(string(jsonData))
	case "yaml":
		yamlData, err := yaml.Marshal(data)
		if err != nil {
			return fmt.Errorf("YAML 格式化失败: %w", err)
		}
		fmt.Println(string(yamlData))
	default:
		// 表格格式 - 对于简单数据结构尝试表格输出，复杂结构使用 JSON
		if err := printTable(data); err != nil {
			// 如果表格输出失败，回退到 JSON 格式
			jsonData, err := json.MarshalIndent(data, "", "  ")
			if err != nil {
				return fmt.Errorf("表格格式化失败: %w", err)
			}
			fmt.Println(string(jsonData))
		}
	}
	return nil
}

// printTable 尝试以表格形式输出数据
func printTable(data interface{}) error {
	if data == nil {
		fmt.Println("空数据")
		return nil
	}

	// 使用反射处理不同类型的输入数据
	v := reflect.ValueOf(data)

	// 处理指针类型
	for v.Kind() == reflect.Ptr {
		if v.IsNil() {
			fmt.Println("空数据")
			return nil
		}
		v = v.Elem()
	}

	// 创建表格写入器
	w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)

	switch v.Kind() {
	case reflect.Slice:
		// 处理切片数据
		if v.Len() == 0 {
			fmt.Println("空列表")
			return nil
		}

		// 获取第一个元素来确定字段
		first := v.Index(0)
		for first.Kind() == reflect.Ptr || first.Kind() == reflect.Interface {
			first = first.Elem()
		}

		if first.Kind() == reflect.Struct {
			// 处理结构体切片
			printStructSlice(w, v)
		} else {
			// 处理基本类型切片
			printBasicSlice(w, v)
		}
	case reflect.Struct:
		// 处理单个结构体
		printStruct(w, v)
	case reflect.Map:
		// 处理映射
		printMap(w, v)
	default:
		// 处理基本类型
		fmt.Fprintf(w, "值\t%v\n", v.Interface())
	}

	return w.Flush()
}

// printStructSlice 打印结构体切片
func printStructSlice(w *tabwriter.Writer, slice reflect.Value) {
	if slice.Len() == 0 {
		return
	}

	// 获取结构体类型
	first := slice.Index(0)
	for first.Kind() == reflect.Ptr || first.Kind() == reflect.Interface {
		first = first.Elem()
	}

	typ := first.Type()
	fieldNames := make([]string, 0)
	fieldTags := make([]string, 0)

	// 收集字段名（优先使用 json tag）
	for i := 0; i < typ.NumField(); i++ {
		field := typ.Field(i)
		if field.PkgPath != "" { // 跳过未导出字段
			continue
		}

		fieldNames = append(fieldNames, field.Name)
		tag := field.Tag.Get("json")
		if tag != "" {
			// 去除 omitempty 等选项
			tag = strings.Split(tag, ",")[0]
			if tag != "-" {
				fieldTags = append(fieldTags, tag)
			} else {
				fieldTags = append(fieldTags, field.Name)
			}
		} else {
			fieldTags = append(fieldTags, field.Name)
		}
	}

	// 打印表头
	fmt.Fprintln(w, strings.Join(fieldTags, "\t"))

	// 打印分隔线
	sep := make([]string, len(fieldTags))
	for i := range sep {
		sep[i] = strings.Repeat("-", len(fieldTags[i]))
	}
	fmt.Fprintln(w, strings.Join(sep, "\t"))

	// 打印数据行
	for i := 0; i < slice.Len(); i++ {
		item := slice.Index(i)
		for item.Kind() == reflect.Ptr || item.Kind() == reflect.Interface {
			item = item.Elem()
		}

		values := make([]string, 0, len(fieldNames))
		for _, fieldName := range fieldNames {
			field := item.FieldByName(fieldName)
			if field.IsValid() {
				values = append(values, fmt.Sprintf("%v", field.Interface()))
			} else {
				values = append(values, "")
			}
		}
		fmt.Fprintln(w, strings.Join(values, "\t"))
	}
}

// printBasicSlice 打印基本类型切片
func printBasicSlice(w *tabwriter.Writer, slice reflect.Value) {
	fmt.Fprintln(w, "值")
	fmt.Fprintln(w, "---")
	for i := 0; i < slice.Len(); i++ {
		fmt.Fprintf(w, "%v\n", slice.Index(i).Interface())
	}
}

// printStruct 打印结构体
func printStruct(w *tabwriter.Writer, v reflect.Value) {
	typ := v.Type()
	for i := 0; i < v.NumField(); i++ {
		field := typ.Field(i)
		if field.PkgPath != "" { // 跳过未导出字段
			continue
		}

		fieldValue := v.Field(i)
		tag := field.Tag.Get("json")
		if tag != "" {
			tag = strings.Split(tag, ",")[0]
			if tag == "-" {
				continue
			}
		} else {
			tag = field.Name
		}

		fmt.Fprintf(w, "%s\t%v\n", tag, fieldValue.Interface())
	}
}

// printMap 打印映射
func printMap(w *tabwriter.Writer, v reflect.Value) {
	keys := v.MapKeys()
	fmt.Fprintln(w, "键\t值")
	fmt.Fprintln(w, "---\t---")
	for _, key := range keys {
		value := v.MapIndex(key)
		fmt.Fprintf(w, "%v\t%v\n", key.Interface(), value.Interface())
	}
}

func buildWebSocketURL(baseURL, wsPath string) string {
	// 将 HTTP URL 转换为 WebSocket URL
	if len(baseURL) >= 7 && baseURL[:7] == "http://" {
		baseURL = "ws://" + baseURL[7:]
	} else if len(baseURL) >= 8 && baseURL[:8] == "https://" {
		baseURL = "wss://" + baseURL[8:]
	}

	// 确保路径以 / 开头
	if wsPath != "" && wsPath[0] != '/' {
		wsPath = "/" + wsPath
	}

	fullURL := baseURL + wsPath

	return fullURL
}
